// export.js
// 数据导出与报告生成模块

console.log('export.js文件开始加载 - 立即执行');

/**
 * ExportModule 负责实验数据的导出（CSV）和实验报告生成
 */
export const ExportModule = {
  /**
   * 初始化导出模块，绑定导出按钮事件
   */
  init() {
    console.log('ExportModule.init()被调用');
    
    // 动态创建导出按钮并绑定事件
    let exportBtn = document.getElementById('exportBtn');
    if (!exportBtn) {
      exportBtn = document.createElement('button');
      exportBtn.id = 'exportBtn';
      exportBtn.textContent = '导出数据';
      exportBtn.style.margin = '10px 0 0 0';
    }
    // 新增：生成可视化分析按钮
    console.log('准备创建可视化分析按钮');
    let visualizationBtn = document.getElementById('visualizationBtn');
    if (!visualizationBtn) {
      visualizationBtn = document.createElement('button');
      visualizationBtn.id = 'visualizationBtn';
      visualizationBtn.textContent = '生成可视化分析';
      console.log('可视化分析按钮创建完成');
      visualizationBtn.style.cssText = `
        position: static;
        background: linear-gradient(45deg, #ff6b6b, #ee5a24);
        color: white;
        border: none;
        padding: 15px 25px;
        border-radius: 25px;
        cursor: pointer;
        font-size: 1.1rem;
        font-weight: bold;
        box-shadow: 0 4px 15px rgba(255, 107, 107, 0.4);
        transition: all 0.3s ease;
        margin: 20px auto;
        display: block;
        width: fit-content;`;
      visualizationBtn.addEventListener('mouseenter', () => {
        visualizationBtn.style.transform = 'translateY(-3px)';
        visualizationBtn.style.boxShadow = '0 6px 20px rgba(255, 107, 107, 0.6)';
      });
      visualizationBtn.addEventListener('mouseleave', () => {
        visualizationBtn.style.transform = 'translateY(0)';
        visualizationBtn.style.boxShadow = '0 4px 15px rgba(255, 107, 107, 0.4)';
      });
    }
    // 新增：生成实验报告按钮
    let reportBtn = document.getElementById('reportBtn');
    if (!reportBtn) {
      reportBtn = document.createElement('button');
      reportBtn.id = 'reportBtn';
      reportBtn.textContent = '生成实验报告';
      reportBtn.style.cssText = `
        position: static;
        background: linear-gradient(45deg, #4caf50, #2e7d32);
        color: white;
        border: none;
        padding: 15px 25px;
        border-radius: 25px;
        cursor: pointer;
        font-size: 1.1rem;
        font-weight: bold;
        box-shadow: 0 4px 15px rgba(76, 175, 80, 0.4);
        transition: all 0.3s ease;
        margin: 20px auto;
        display: block;
        width: fit-content;`;
      reportBtn.addEventListener('mouseenter', () => {
        reportBtn.style.transform = 'translateY(-3px)';
        reportBtn.style.boxShadow = '0 6px 20px rgba(76, 175, 80, 0.6)';
      });
      reportBtn.addEventListener('mouseleave', () => {
        reportBtn.style.transform = 'translateY(0)';
        reportBtn.style.boxShadow = '0 4px 15px rgba(76, 175, 80, 0.4)';
      });
    }
    // 创建按钮容器并插入到controls-section最下方
    console.log('准备创建按钮容器');
    let buttonContainer = document.getElementById('exportButtonContainer');
    if (!buttonContainer) {
      buttonContainer = document.createElement('div');
      buttonContainer.id = 'exportButtonContainer';
      console.log('按钮容器创建完成');
      buttonContainer.style.cssText = `
        display: flex;
        gap: 20px;
        justify-content: center;
        align-items: center;
        margin: 20px auto;
        flex-wrap: wrap;`;
    }
    // 清空容器再添加按钮，避免重复
    buttonContainer.innerHTML = '';
    buttonContainer.appendChild(exportBtn);
    buttonContainer.appendChild(visualizationBtn);
    buttonContainer.appendChild(reportBtn);
    const controlsSection = document.querySelector('.controls-section');
    if (controlsSection) {
      controlsSection.appendChild(buttonContainer);
    } else {
      document.body.appendChild(buttonContainer);
    }
    // 绑定事件
    exportBtn.onclick = () =>{
      this.exportCSV();
      console.log('导出数据按钮被点击');
    }
    visualizationBtn.onclick = () => {
      console.log('生成可视化分析按钮被点击');
      this.showVisualizationAnalysis();
    };
    reportBtn.onclick = () => {
      console.log('生成实验报告按钮被点击');
      this.generateReport();
    };  
  },

  /**
   * 导出CSV数据
   * 依赖 window.experimentGroups
   */
  exportCSV() {
    if (!window.experimentGroups || !window.experimentGroups.length) {
      alert('没有可导出的实验数据！');
      return;
    }
    let csv = '实验编号,初始角度(°),摆长(cm),周期编号,本周期时长(s),累计时长(s),重力加速度(m/s²)\n';
    window.experimentGroups.forEach((exp, expIdx) => {
      if (exp.periods && exp.periods.length > 0) {
        exp.periods.forEach((p, i) => {
          csv += [
            expIdx + 1,
            exp.initialAngle,
            exp.length,
            p.index,
            p.duration.toFixed(4),
            p.total.toFixed(4),
            (i === 0 ? (exp.gravity?.toFixed(4) || '') : '')
          ].join(',') + '\n';
        });
      } else {
        csv += [
          expIdx + 1,
          exp.initialAngle,
          exp.length,
          '', '', '', exp.gravity?.toFixed(4) || ''
        ].join(',') + '\n';
      }
    });
    // 添加UTF-8 BOM头
    const BOM = '\uFEFF';
    const blob = new Blob([BOM + csv], {type: 'text/csv'});
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = '实验数据.csv';
    a.click();
    URL.revokeObjectURL(url);
  },

  /**
   * 生成实验报告（HTML文件下载）
   * 依赖 processExperimentData
   */
  generateReport() {
    const data = this.processExperimentData();
    
    // 创建报告HTML内容
    let htmlContent = `
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>单摆测重力加速度实验报告</title>
  <style>
    body {
      font-family: "Microsoft YaHei", Arial, sans-serif;
      line-height: 1.6;
      max-width: 1000px;
      margin: 0 auto;
      padding: 20px;
      color: #333;
    }
    h1, h2 {
      color: #2c3e50;
      border-bottom: 2px solid #eee;
      padding-bottom: 10px;
    }
    .formula {
      background: #f8f9fa;
      padding: 10px;
      border-radius: 5px;
      margin: 10px 0;
      text-align: center;
      font-style: italic;
    }
    .chart-container {
      display: flex;
      justify-content: center;
      gap: 20px;
      margin: 20px 0;
      flex-wrap: wrap;
    }
    .chart {
      border: 1px solid #ddd;
      padding: 10px;
      border-radius: 5px;
      background: white;
    }
    .question {
      background: #f5f6fa;
      padding: 15px;
      border-left: 4px solid #5d6d7e;
      margin: 10px 0;
    }
    .answer {
      margin-left: 20px;
      color: #2c3e50;
    }
  </style>
</head>
<body>
  <h1>单摆测重力加速度实验报告</h1>
  
  <p>摆测重力加速度伽利略在比萨大教堂内观察一个圣灯缓慢地摆动时，用他的脉搏跳动作为计时器计算圣灯摆动的周期。他发现连续摆动的圣灯，每次摆动的时间间隔是相等的，与圣灯摆动的振幅无关，并用实验证实了观察的结果。这就是单摆的等时性原理。用单摆来测量重力加速度简单方便，因为单摆的振动周期取决于振动系统本身的性质，即取决于重力加速度g和摆长L.只需要测出摆长L和摆动周期T，就可算出g的值。地球上各个地区重力加速度g的数值，随该地区的地理纬度和相对于海平面的高度的不同而稍有差异。</p>

  <h2>【实验目的】</h2>
  <ol>
    <li>掌握用单摆测量重力加速度的方法并分析重力加速度与摆长之间的关系。</li>
    <li>研究单摆的周期与单摆的摆长、摆动角度之间的关系。</li>
    <li>学习用作图法处理测量数据。</li>
  </ol>

  <h2>【实验原理】</h2>
  <p>一根长为L的不可伸长的细线，上端固定，下端悬挂一个质量为m的小球。当细线质量比小球的质量小很多，而且小球的直径又比细线的长度小很多，摆角小于或等于10°,空气阻力不计，此种装置称为单摆。</p>
  
  <p>如果把小球稍微拉开一定距离，小球在重力作用下可在竖直平面内作往复运动，一个完整的往复运动所用的时间称为一个周期。</p>

  <p>可以证明单摆的周期T满足下面公式：</p>
  <div class="formula">
    T = 2π√(L/g)
  </div>

  <p>式中L为单摆摆长。单摆摆长是指上端悬挂点到球心之间的距离，g为重力加速度。如果测量得出周期T，单摆的摆长L，利用上面式子可计算出当地的重力加速度g.从上面公式可知T²和L具有线性关系，对不同的单摆摆长L测量得出相对应的周期，可由线的斜率求出g值。</p>

  <p>当摆动角度θ较大(θ>10°)时，单摆的振动周期T和摆动的角度θ之间存在下列关系：</p>
  <div class="formula">
    T = T₀(1 + (1/16)sin²(θ/2) + ...)
  </div>

  <h2>【实验仪器】</h2>
  <p>单摆实验装置，光电门，米尺，游标卡尺。</p>

  <h2>【数据处理与结果】</h2>
  <h3>实验1：周期与摆长的关系</h3>
  <div class="chart-container">
    <div class="chart">
      <canvas id="reportChart1" width="400" height="300"></canvas>
      <p>图1：T vs L 散点图与曲线拟合</p>
    </div>
    <div class="chart">
      <canvas id="reportChart2" width="400" height="300"></canvas>
      <p>图2：T vs √L 散点图与线性拟合</p>
    </div>
  </div>

  <div class="question">
    <p><strong>思考题1：</strong>为什么是曲线不是直线？能否找到一种方法，让数据变成线性关系？</p>
    <div class="answer" id="answer1"></div>
  </div>

  <div class="question">
    <p><strong>思考题2：</strong>为什么选择√L？是否有其他方法得到线性？</p>
    <div class="answer" id="answer2"></div>
  </div>

  <h3>实验2：重力加速度与摆长的关系</h3>
  <div class="chart-container">
    <div class="chart">
      <canvas id="reportChart3" width="400" height="300"></canvas>
      <p>图3：g vs L 散点图与曲线拟合</p>
    </div>
  </div>

  <div class="question">
    <p><strong>思考题1：</strong>为什么g在小摆长和大摆长时偏小，中摆长时稳定？</p>
    <div class="answer" id="answer4"></div>
  </div>

  <div class="question">
    <p><strong>思考题2：</strong>如何改进实验让重力加速度的测量更精准呢？</p>
    <div class="answer" id="answer6"></div>
  </div>

  <h3>实验3：周期与摆角的关系</h3>
  <div class="chart-container">
    <div class="chart">
      <canvas id="reportChart4" width="400" height="300"></canvas>
      <p>图4：小摆角下的周期变化 (1-10°)</p>
    </div>
    <div class="chart">
      <canvas id="reportChart5" width="400" height="300"></canvas>
      <p>图5：大摆角下的周期变化 (30-90°)</p>
    </div>
  </div>

  <div class="question">
    <p><strong>思考题1：</strong>为什么小摆角下得到的图像周期基本不变？</p>
    <div class="answer" id="answer7"></div>
  </div>

  <div class="question">
    <p><strong>思考题2：</strong>为什么大摆角下周期变化幅度这么大？</p>
    <div class="answer" id="answer9"></div>
  </div>

  <h2>【注意事项】</h2>
  <p>单摆必须在竖直面内摆动,防止形成锥摆。</p>

  <h2>【分析讨论题】</h2>
  <div class="question">
    <p><strong>1. </strong>单摆在摆动中受空气阻力的影响,摆幅会越来越小,试问它的周期是否会变化?请根据实验观察进行回答,并说明理论依据。</p>
    <div class="answer"></div>
  </div>

  <div class="question">
    <p><strong>2. </strong>根据间接测量误差传递公式分析本实验中哪个物理量的测量对g测量影响最大?应采用什么方法减小测量误差?</p>
    <div class="answer"></div>
  </div>

  <script>
    // 获取学生填写的答案
    function getAnswers() {
      const answers = document.querySelectorAll('textarea');
      answers.forEach((answer, index) => {
        const answerDiv = document.getElementById('answer' + (index + 1));
        if (answerDiv) {
          answerDiv.textContent = answer.value || '（未作答）';
        }
      });
    }

    // 绘制图表
    function drawReportCharts() {
      // 复用可视化分析中的图表绘制函数
      const charts = [
        { canvas: 'reportChart1', drawFunc: window.ExportModule.drawTvsLChart },
        { canvas: 'reportChart2', drawFunc: window.ExportModule.drawTvsSqrtLChart },
        { canvas: 'reportChart3', drawFunc: window.ExportModule.drawGvsLChart },
        { canvas: 'reportChart4', drawFunc: window.ExportModule.drawTvsSmallThetaChart },
        { canvas: 'reportChart5', drawFunc: window.ExportModule.drawTvsLargeThetaChart }
      ];

      charts.forEach(chart => {
        const canvas = document.getElementById(chart.canvas);
        if (canvas) {
          chart.drawFunc(window.experimentData);
        }
      });
    }

    // 页面加载完成后执行
    window.onload = function() {
      getAnswers();
      drawReportCharts();
    };
  </script>
</body>
</html>`;

    // 创建并下载报告
    const blob = new Blob([htmlContent], { type: 'text/html' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = '单摆测重力加速度实验报告.html';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  },

  /**
   * 显示可视化分析界面
   */
  showVisualizationAnalysis() {
    console.log('showVisualizationAnalysis函数被调用');
    
    // 移除已存在的可视化界面
    const existingModal = document.getElementById('visualizationModal');
    if (existingModal) {
      existingModal.remove();
    }

    // 获取实验数据
    console.log('准备调用processExperimentData()');
    const data = this.processExperimentData();
    console.log('processExperimentData()返回的数据:', data);
    
    // 创建模态框
    const modal = document.createElement('div');
    modal.id = 'visualizationModal';
    modal.style.cssText = `
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background: rgba(0, 0, 0, 0.8);
      z-index: 10000;
      overflow-y: auto;
      display: flex;
      justify-content: center;
      align-items: flex-start;
      padding: 20px;
    `;

    // 创建内容容器
    const content = document.createElement('div');
    content.style.cssText = `
      background: white;
      border-radius: 15px;
      padding: 30px;
      max-width: 1200px;
      width: 100%;
      max-height: 90vh;
      overflow-y: auto;
      position: relative;
      display: flex;
      flex-direction: column;
    `;

    // 创建关闭按钮
    const closeBtn = document.createElement('button');
    closeBtn.textContent = '×';
    closeBtn.style.cssText = `
      position: absolute;
      top: 15px;
      right: 20px;
      background: none;
      border: none;
      font-size: 24px;
      cursor: pointer;
      color: #666;
      width: 30px;
      height: 30px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
      transition: background 0.3s;
    `;
    closeBtn.onmouseenter = () => closeBtn.style.background = '#f0f0f0';
    closeBtn.onmouseleave = () => closeBtn.style.background = 'none';
    closeBtn.onclick = () => modal.remove();

    // 标题
    const title = document.createElement('h1');
    title.textContent = '单摆实验数据分析';
    title.style.cssText = `
      text-align: center;
      color: #333;
      margin-bottom: 20px;
      font-size: 2rem;
      font-weight: bold;
    `;

    // 创建标签页容器
    const tabContainer = document.createElement('div');
    tabContainer.style.cssText = `
      display: flex;
      justify-content: center;
      gap: 20px;
      margin-bottom: 30px;
    `;

    // 创建标签页按钮
    const tab1 = document.createElement('button');
    tab1.textContent = '周期与摆长关系';
    const tab2 = document.createElement('button');
    tab2.textContent = '重力加速度与摆长关系';
    const tab3 = document.createElement('button');
    tab3.textContent = '周期与摆角关系';

    const tabStyle = `
      padding: 12px 30px;
      border: none;
      border-radius: 25px;
      cursor: pointer;
      font-size: 1.1rem;
      transition: all 0.3s;
      white-space: nowrap;
      font-weight: 500;
      background: #f0f0f0;
      color: #666;
    `;

    [tab1, tab2, tab3].forEach(tab => {
      tab.style.cssText = tabStyle;
    });

    const setActiveTab = (activeTab) => {
      [tab1, tab2, tab3].forEach(tab => {
        if (tab === activeTab) {
          tab.style.background = '#4caf50';
          tab.style.color = 'white';
          tab.style.boxShadow = '0 2px 8px rgba(76, 175, 80, 0.3)';
        } else {
          tab.style.background = '#f0f0f0';
          tab.style.color = '#666';
          tab.style.boxShadow = 'none';
        }
      });
    };

    // 添加标签页到容器
    tabContainer.appendChild(tab1);
    tabContainer.appendChild(tab2);
    tabContainer.appendChild(tab3);

    // 创建内容容器
    const contentWrapper = document.createElement('div');
    contentWrapper.style.cssText = `
      flex: 1;
      overflow-y: auto;
    `;

    // 按顺序添加元素
    content.appendChild(closeBtn);
    content.appendChild(title);
    content.appendChild(tabContainer);
    content.appendChild(contentWrapper);

    // 创建三个内容面板
    const content1 = document.createElement('div');
    content1.style.cssText = `
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 30px;
      margin-top: 20px;
    `;

    // 左侧：T vs L 图表和问题
    const leftColumn1 = document.createElement('div');
    leftColumn1.style.cssText = `
      display: flex;
      flex-direction: column;
      gap: 20px;
    `;

    // T vs L 图表容器
    const chart1Container = document.createElement('div');
    chart1Container.style.cssText = `
      border: 2px solid #e0e0e0;
      border-radius: 10px;
      padding: 20px;
      background: #fafafa;
    `;

    const chart1Title = document.createElement('h3');
    chart1Title.textContent = 'T vs L 散点图与曲线拟合';
    chart1Title.style.cssText = `
      text-align: center;
      margin-bottom: 15px;
      color: #333;
    `;

    const chart1Canvas = document.createElement('canvas');
    chart1Canvas.id = 'chart1';
    chart1Canvas.width = 400;
    chart1Canvas.height = 300;
    chart1Canvas.style.cssText = `
      width: 100%;
      height: 300px;
      border: 1px solid #ddd;
      border-radius: 5px;
      background: white;
    `;

    chart1Container.appendChild(chart1Title);
    chart1Container.appendChild(chart1Canvas);

    // 问题1
    const question1Container = document.createElement('div');
    question1Container.style.cssText = `
      border: 2px solid #ff6b6b;
      border-radius: 10px;
      padding: 20px;
      background: #fff5f5;
    `;

    const question1 = document.createElement('p');
    question1.textContent = '为什么是曲线不是直线？能否找到一种方法，让数据变成线性关系？';
    question1.style.cssText = `
      font-weight: bold;
      color: #d32f2f;
      margin-bottom: 15px;
      font-size: 1.1rem;
    `;

    const answer1 = document.createElement('textarea');
    answer1.placeholder = '请在这里输入你的思考...';
    answer1.style.cssText = `
      width: 100%;
      min-height: 80px;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 5px;
      resize: vertical;
      font-family: inherit;
    `;

    question1Container.appendChild(question1);
    question1Container.appendChild(answer1);

    leftColumn1.appendChild(chart1Container);
    leftColumn1.appendChild(question1Container);

    // 右侧：T vs √L 图表和问题
    const rightColumn1 = document.createElement('div');
    rightColumn1.style.cssText = `
      display: flex;
      flex-direction: column;
      gap: 20px;
    `;

    // 理论说明
    const theoryContainer1 = document.createElement('div');
    theoryContainer1.style.cssText = `
      border: 2px solid #4caf50;
      border-radius: 10px;
      padding: 20px;
      background: #f1f8e9;
    `;

    const theoryText1 = document.createElement('p');
    theoryText1.innerHTML = '<strong>单摆周期公式：</strong>T = 2π√(L/g)<br><br>对L开根号后：T = (2π/√g)·√L，呈线性关系';
    theoryText1.style.cssText = `
      color: #2e7d32;
      font-size: 1.1rem;
      line-height: 1.6;
      text-align: center;
    `;

    theoryContainer1.appendChild(theoryText1);

    // T vs √L 图表容器
    const chart2Container = document.createElement('div');
    chart2Container.style.cssText = `
      border: 2px solid #e0e0e0;
      border-radius: 10px;
      padding: 20px;
      background: #fafafa;
    `;

    const chart2Title = document.createElement('h3');
    chart2Title.textContent = 'T vs √L 散点图与线性拟合';
    chart2Title.style.cssText = `
      text-align: center;
      margin-bottom: 15px;
      color: #333;
    `;

    const chart2Canvas = document.createElement('canvas');
    chart2Canvas.id = 'chart2';
    chart2Canvas.width = 400;
    chart2Canvas.height = 300;
    chart2Canvas.style.cssText = `
      width: 100%;
      height: 300px;
      border: 1px solid #ddd;
      border-radius: 5px;
      background: white;
    `;

    chart2Container.appendChild(chart2Title);
    chart2Container.appendChild(chart2Canvas);

    // 问题2
    const question2Container = document.createElement('div');
    question2Container.style.cssText = `
      border: 2px solid #ff6b6b;
      border-radius: 10px;
      padding: 20px;
      background: #fff5f5;
    `;

    const question2 = document.createElement('p');
    question2.textContent = '为什么选择√L？是否有其他方法得到线性？';
    question2.style.cssText = `
      font-weight: bold;
      color: #d32f2f;
      margin-bottom: 15px;
      font-size: 1.1rem;
    `;

    const answer2 = document.createElement('textarea');
    answer2.placeholder = '请在这里输入你的思考...';
    answer2.style.cssText = `
      width: 100%;
      min-height: 80px;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 5px;
      resize: vertical;
      font-family: inherit;
    `;

    question2Container.appendChild(question2);
    question2Container.appendChild(answer2);

    rightColumn1.appendChild(theoryContainer1);
    rightColumn1.appendChild(chart2Container);
    rightColumn1.appendChild(question2Container);

    content1.appendChild(leftColumn1);
    content1.appendChild(rightColumn1);

    const content2 = document.createElement('div');
    content2.style.cssText = `
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 30px;
      margin-top: 20px;
      display: none;
    `;

    // 左侧：g vs L 图
    const leftColumn2 = document.createElement('div');
    leftColumn2.style.cssText = `
      display: flex;
      flex-direction: column;
      gap: 20px;
    `;

    // 理论说明
    const theoryContainer2 = document.createElement('div');
    theoryContainer2.style.cssText = `
      border: 2px solid #4caf50;
      border-radius: 10px;
      padding: 20px;
      background: #f1f8e9;
    `;

    const theoryText2 = document.createElement('p');
    theoryText2.innerHTML = '<strong>重力加速度计算公式：</strong>g = 4π²L/T²<br><br>当地标准重力加速度：9.873 m/s²';
    theoryText2.style.cssText = `
      color: #2e7d32;
      font-size: 1.1rem;
      line-height: 1.6;
      text-align: center;
    `;

    theoryContainer2.appendChild(theoryText2);

    // g vs L 图表容器
    const chart3Container = document.createElement('div');
    chart3Container.style.cssText = `
      border: 2px solid #e0e0e0;
      border-radius: 10px;
      padding: 20px;
      background: #fafafa;
    `;

    const chart3Title = document.createElement('h3');
    chart3Title.textContent = 'g vs L 散点图与曲线拟合';
    chart3Title.style.cssText = `
      text-align: center;
      margin-bottom: 15px;
      color: #333;
    `;

    const chart3Canvas = document.createElement('canvas');
    chart3Canvas.id = 'chart3';
    chart3Canvas.width = 400;
    chart3Canvas.height = 300;
    chart3Canvas.style.cssText = `
      width: 100%;
      height: 300px;
      border: 1px solid #ddd;
      border-radius: 5px;
      background: white;
    `;

    chart3Container.appendChild(chart3Title);
    chart3Container.appendChild(chart3Canvas);

    leftColumn2.appendChild(theoryContainer2);
    leftColumn2.appendChild(chart3Container);

    // 右侧：问题和解释
    const rightColumn2 = document.createElement('div');
    rightColumn2.style.cssText = `
      display: flex;
      flex-direction: column;
      gap: 20px;
    `;

    // 误差解释
    const errorExplanation = document.createElement('div');
    errorExplanation.style.cssText = `
      border: 2px solid #ff9800;
      border-radius: 10px;
      padding: 20px;
      background: #fff3e0;
    `;

    const errorText = document.createElement('p');
    errorText.innerHTML = '短摆长下摆速较快，光束覆盖区域的时间差会放大误差。会导致周期有微弱变大会导致重力加速度偏小';
    errorText.style.cssText = `
      color: #e65100;
      font-size: 1.1rem;
      line-height: 1.6;
    `;

    errorExplanation.appendChild(errorText);

    // 问题4
    const question4Container = document.createElement('div');
    question4Container.style.cssText = `
      border: 2px solid #ff6b6b;
      border-radius: 10px;
      padding: 20px;
      background: #fff5f5;
    `;

    const question4 = document.createElement('p');
    question4.textContent = '已知当地的g为9.873，为什么g在小摆长和大摆长时偏小，中摆长时稳定？';
    question4.style.cssText = `
      font-weight: bold;
      color: #d32f2f;
      margin-bottom: 15px;
      font-size: 1.1rem;
    `;

    const answer4 = document.createElement('textarea');
    answer4.placeholder = '请在这里输入你的思考...';
    answer4.style.cssText = `
      width: 100%;
      min-height: 80px;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 5px;
      resize: vertical;
      font-family: inherit;
    `;

    question4Container.appendChild(question4);
    question4Container.appendChild(answer4);

    // 问题5
    const question5Container = document.createElement('div');
    question5Container.style.cssText = `
      border: 2px solid #ff6b6b;
      border-radius: 10px;
      padding: 20px;
      background: #fff5f5;
    `;

    const question5 = document.createElement('p');
    question5.textContent = '长摆长下阻力更明显，同时摆绳并非完全刚性，在实验过程中会出现微小伸缩，并在长摆长下更明显？';
    question5.style.cssText = `
      font-weight: bold;
      color: #d32f2f;
      margin-bottom: 15px;
      font-size: 1.1rem;
    `;

    const answer5 = document.createElement('textarea');
    answer5.placeholder = '请在这里输入你的思考...';
    answer5.style.cssText = `
      width: 100%;
      min-height: 80px;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 5px;
      resize: vertical;
      font-family: inherit;
    `;

    question5Container.appendChild(question5);
    question5Container.appendChild(answer5);

    rightColumn2.appendChild(errorExplanation);
    rightColumn2.appendChild(question4Container);
    rightColumn2.appendChild(question5Container);

    content2.appendChild(leftColumn2);
    content2.appendChild(rightColumn2);

    const content3 = document.createElement('div');
    content3.style.cssText = `
      display: grid;
      grid-template-columns: 1fr 1fr;
      gap: 30px;
      margin-top: 20px;
      display: none;
    `;

    // 左侧：小摆角分析
    const leftColumn3 = document.createElement('div');
    leftColumn3.style.cssText = `
      display: flex;
      flex-direction: column;
      gap: 20px;
    `;

    // 小摆角图表容器
    const chart4Container = document.createElement('div');
    chart4Container.style.cssText = `
      border: 2px solid #e0e0e0;
      border-radius: 10px;
      padding: 20px;
      background: #fafafa;
    `;

    const chart4Title = document.createElement('h3');
    chart4Title.textContent = '小摆角下的周期变化 (1-10°)';
    chart4Title.style.cssText = `
      text-align: center;
      margin-bottom: 15px;
      color: #333;
    `;

    const chart4Canvas = document.createElement('canvas');
    chart4Canvas.id = 'chart4';
    chart4Canvas.width = 400;
    chart4Canvas.height = 300;
    chart4Canvas.style.cssText = `
      width: 100%;
      height: 300px;
      border: 1px solid #ddd;
      border-radius: 5px;
      background: white;
    `;

    chart4Container.appendChild(chart4Title);
    chart4Container.appendChild(chart4Canvas);

    // 问题7
    const question7Container = document.createElement('div');
    question7Container.style.cssText = `
      border: 2px solid #ff6b6b;
      border-radius: 10px;
      padding: 20px;
      background: #fff5f5;
    `;

    const question7 = document.createElement('p');
    question7.textContent = '为什么得到的图像周期基本不变？';
    question7.style.cssText = `
      font-weight: bold;
      color: #d32f2f;
      margin-bottom: 15px;
      font-size: 1.1rem;
    `;

    const answer7 = document.createElement('textarea');
    answer7.placeholder = '请在这里输入你的思考...';
    answer7.style.cssText = `
      width: 100%;
      min-height: 80px;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 5px;
      resize: vertical;
      font-family: inherit;
    `;

    question7Container.appendChild(question7);
    question7Container.appendChild(answer7);

    leftColumn3.appendChild(chart4Container);
    leftColumn3.appendChild(question7Container);

    // 右侧：大摆角分析
    const rightColumn3 = document.createElement('div');
    rightColumn3.style.cssText = `
      display: flex;
      flex-direction: column;
      gap: 20px;
    `;

    // 理论说明
    const theoryContainer3 = document.createElement('div');
    theoryContainer3.style.cssText = `
      border: 2px solid #ff9800;
      border-radius: 10px;
      padding: 20px;
      background: #fff3e0;
    `;

    const theoryText3 = document.createElement('p');
    theoryText3.innerHTML = '大摆角下sinθ≠θ<br>单摆不再做简谐运动而是非线性运动，周期也需要进行角度修正。';
    theoryText3.style.cssText = `
      color: #e65100;
      font-size: 1.1rem;
      line-height: 1.6;
      text-align: center;
    `;

    theoryContainer3.appendChild(theoryText3);

    // 注释掉大摆角图表容器
    /*
    // 大摆角图表容器
    const chart5Container = document.createElement('div');
    chart5Container.style.cssText = `
      border: 2px solid #e0e0e0;
      border-radius: 10px;
      padding: 20px;
      background: #fafafa;
    `;

    const chart5Title = document.createElement('h3');
    chart5Title.textContent = '大摆角下的周期变化 (30-90°)';
    chart5Title.style.cssText = `
      text-align: center;
      margin-bottom: 15px;
      color: #333;
    `;

    const chart5Canvas = document.createElement('canvas');
    chart5Canvas.id = 'chart5';
    chart5Canvas.width = 400;
    chart5Canvas.height = 300;
    chart5Canvas.style.cssText = `
      width: 100%;
      height: 300px;
      border: 1px solid #ddd;
      border-radius: 5px;
      background: white;
    `;

    chart5Container.appendChild(chart5Title);
    chart5Container.appendChild(chart5Canvas);

    // 问题9
    const question9Container = document.createElement('div');
    question9Container.style.cssText = `
      border: 2px solid #ff6b6b;
      border-radius: 10px;
      padding: 20px;
      background: #fff5f5;
    `;

    const question9 = document.createElement('p');
    question9.textContent = '为什么大摆角下周期变化幅度这么大？';
    question9.style.cssText = `
      font-weight: bold;
      color: #d32f2f;
      margin-bottom: 15px;
      font-size: 1.1rem;
    `;

    const answer9 = document.createElement('textarea');
    answer9.placeholder = '请在这里输入你的思考...';
    answer9.style.cssText = `
      width: 100%;
      min-height: 80px;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 5px;
      resize: vertical;
      font-family: inherit;
    `;

    question9Container.appendChild(question9);
    question9Container.appendChild(answer9);

    rightColumn3.appendChild(theoryContainer3);
    rightColumn3.appendChild(chart5Container);
    rightColumn3.appendChild(question9Container);
    */
    
    // 只添加理论说明，不添加图表和问题
    rightColumn3.appendChild(theoryContainer3);

    content3.appendChild(leftColumn3);
    content3.appendChild(rightColumn3);

    // 将内容面板添加到contentWrapper
    contentWrapper.appendChild(content1);
    contentWrapper.appendChild(content2);
    contentWrapper.appendChild(content3);

    // 标签页切换逻辑
    tab1.onclick = () => {
      setActiveTab(tab1);
      content1.style.display = 'grid';
      content2.style.display = 'none';
      content3.style.display = 'none';
    };

    tab2.onclick = () => {
      setActiveTab(tab2);
      content1.style.display = 'none';
      content2.style.display = 'grid';
      content3.style.display = 'none';
    };

    tab3.onclick = () => {
      setActiveTab(tab3);
      content1.style.display = 'none';
      content2.style.display = 'none';
      content3.style.display = 'grid';
    };

    // 设置默认激活的标签页
    setActiveTab(tab1);

    modal.appendChild(content);
    document.body.appendChild(modal);

    // 绘制图表
    this.drawCharts(data);
  },

  /**
   * 绘制图表
   */
  drawCharts(data) {
    console.log('drawCharts被调用，数据:', data);
    console.log('window.experimentGroups:', window.experimentGroups);
    
    if (!data || data.length === 0) {
      console.log('没有数据，显示提示信息');
      // 如果没有数据，显示提示信息
      const chart1 = document.getElementById('chart1');
      const chart2 = document.getElementById('chart2');
      const chart3 = document.getElementById('chart3');
      const chart4 = document.getElementById('chart4');
      // const chart5 = document.getElementById('chart5'); // 注释掉chart5
      
      if (chart1) {
        const ctx1 = chart1.getContext('2d');
        ctx1.fillStyle = '#f0f0f0';
        ctx1.fillRect(0, 0, chart1.width, chart1.height);
        ctx1.fillStyle = '#666';
        ctx1.font = '16px Arial';
        ctx1.textAlign = 'center';
        ctx1.fillText('暂无实验数据', chart1.width/2, chart1.height/2);
      }
      
      if (chart2) {
        const ctx2 = chart2.getContext('2d');
        ctx2.fillStyle = '#f0f0f0';
        ctx2.fillRect(0, 0, chart2.width, chart2.height);
        ctx2.fillStyle = '#666';
        ctx2.font = '16px Arial';
        ctx2.textAlign = 'center';
        ctx2.fillText('暂无实验数据', chart2.width/2, chart2.height/2);
      }
      if (chart3) {
        const ctx3 = chart3.getContext('2d');
        ctx3.fillStyle = '#f0f0f0';
        ctx3.fillRect(0, 0, chart3.width, chart3.height);
        ctx3.fillStyle = '#666';
        ctx3.font = '16px Arial';
        ctx3.textAlign = 'center';
        ctx3.fillText('暂无实验数据', chart3.width/2, chart3.height/2);
      }
      if (chart4) {
        const ctx4 = chart4.getContext('2d');
        ctx4.fillStyle = '#f0f0f0';
        ctx4.fillRect(0, 0, chart4.width, chart4.height);
        ctx4.fillStyle = '#666';
        ctx4.font = '16px Arial';
        ctx4.textAlign = 'center';
        ctx4.fillText('暂无小摆角数据', chart4.width/2, chart4.height/2);
      }
      // 注释掉chart5的处理
      /*
      if (chart5) {
        const ctx5 = chart5.getContext('2d');
        ctx5.fillStyle = '#f0f0f0';
        ctx5.fillRect(0, 0, chart5.width, chart5.height);
        ctx5.fillStyle = '#666';
        ctx5.font = '16px Arial';
        ctx5.textAlign = 'center';
        ctx5.fillText('暂无大摆角数据', chart5.width/2, chart5.height/2);
      }
      */
      return;
    }

    console.log('开始绘制图表，数据点数量:', data.length);
    console.log('数据示例:', data[0]);

    // 绘制第一个图表：T vs L
    this.drawTvsLChart(data);
    
    // 绘制第二个图表：T vs √L
    this.drawTvsSqrtLChart(data);

    // 绘制第三个图表：g vs L
    this.drawGvsLChart(data);

    // 绘制第四个图表：T vs θ
    this.drawTvsSmallThetaChart(data);
    // 注释掉大摆角图表：T vs θ
    // this.drawTvsLargeThetaChart(data);
  },

  /**
   * 绘制 T vs L 图表
   */
  drawTvsLChart(data) {
    const canvas = document.getElementById('chart1');
    if (!canvas) return;
    
    const ctx = canvas.getContext('2d');
    const width = canvas.width;
    const height = canvas.height;
    
    // 清空画布
    ctx.clearRect(0, 0, width, height);
    
    // 设置边距
    const margin = 50;
    const plotWidth = width - 2 * margin;
    const plotHeight = height - 2 * margin;
    
    // 找出数据范围
    const lengths = data.map(d => d.length);
    const periods = data.map(d => d.period);
    const minLength = Math.min(...lengths);
    const maxLength = Math.max(...lengths);
    const minPeriod = Math.min(...periods);
    const maxPeriod = Math.max(...periods);
    
    // 处理数据范围为零的情况
    const lengthRange = maxLength - minLength;
    const periodRange = maxPeriod - minPeriod;
    
    // 如果摆长范围为零，设置一个合理的显示范围
    let displayMinLength, displayMaxLength, displayMinPeriod, displayMaxPeriod;
    
    if (lengthRange === 0) {
      // 当摆长相同时，以当前摆长为中心，设置一个合理的显示范围
      displayMinLength = minLength - 20;  // 显示范围：当前摆长±20cm
      displayMaxLength = minLength + 20;
    } else {
      displayMinLength = minLength;
      displayMaxLength = maxLength;
    }
    
    if (periodRange === 0) {
      // 当周期相同时，以当前周期为中心，设置一个合理的显示范围
      displayMinPeriod = minPeriod - 0.5;  // 显示范围：当前周期±0.5s
      displayMaxPeriod = minPeriod + 0.5;
    } else {
      displayMinPeriod = minPeriod;
      displayMaxPeriod = maxPeriod;
    }
    
    const displayLengthRange = displayMaxLength - displayMinLength;
    const displayPeriodRange = displayMaxPeriod - displayMinPeriod;
    
    // 坐标轴
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(margin, margin);
    ctx.lineTo(margin, height - margin);
    ctx.lineTo(width - margin, height - margin);
    ctx.stroke();
    
    // 绘制坐标轴刻度
    ctx.fillStyle = '#333';
    ctx.font = '12px Arial';
    ctx.textAlign = 'center';
    
    // X轴刻度
    const xTicks = 5;
    for (let i = 0; i <= xTicks; i++) {
      const length = displayMinLength + (displayMaxLength - displayMinLength) * i / xTicks;
      const x = margin + (length - displayMinLength) / displayLengthRange * plotWidth;
      const y = height - margin;
      
      // 绘制刻度线
      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x, y + 5);
      ctx.stroke();
      
      // 绘制刻度标签
      ctx.fillText(length.toFixed(0), x, y + 20);
    }
    
    // Y轴刻度
    const yTicks = 5;
    for (let i = 0; i <= yTicks; i++) {
      const period = displayMaxPeriod - (displayMaxPeriod - displayMinPeriod) * i / yTicks;
      const x = margin;
      const y = margin + (period - displayMinPeriod) / displayPeriodRange * plotHeight;
      
      // 绘制刻度线
      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x - 5, y);
      ctx.stroke();
      
      // 绘制刻度标签
      ctx.textAlign = 'right';
      ctx.fillText(period.toFixed(2), x - 10, y + 4);
    }
    
    // 绘制散点
    ctx.fillStyle = '#ff6b6b';
    data.forEach(d => {
      const x = margin + (d.length - displayMinLength) / displayLengthRange * plotWidth;
      const y = height - margin - (d.period - displayMinPeriod) / displayPeriodRange * plotHeight;
      
      ctx.beginPath();
      ctx.arc(x, y, 4, 0, 2 * Math.PI);
      ctx.fill();
    });
    
    // 绘制理论曲线
    ctx.strokeStyle = '#4caf50';
    ctx.lineWidth = 2;
    ctx.beginPath();
    
    const steps = 100;
    for (let i = 0; i <= steps; i++) {
      const length = displayMinLength + displayLengthRange * i / steps;
      const period = 2 * Math.PI * Math.sqrt(length / 100 / 9.8);
      const x = margin + (length - displayMinLength) / displayLengthRange * plotWidth;
      const y = height - margin - (period - displayMinPeriod) / displayPeriodRange * plotHeight;
      
      if (i === 0) {
        ctx.moveTo(x, y);
      } else {
        ctx.lineTo(x, y);
      }
    }
    ctx.stroke();
    
    // 标签
    ctx.fillStyle = '#333';
    ctx.font = '14px Arial';
    ctx.textAlign = 'center';
    ctx.fillText('摆长 L (cm)', width / 2, height - 10);
    
    ctx.save();
    ctx.translate(10, height / 2);
    ctx.rotate(-Math.PI / 2);
    ctx.fillText('周期 T (s)', 0, 0);
    ctx.restore();
  },

  /**
   * 绘制 T vs √L 图表
   */
  drawTvsSqrtLChart(data) {
    const canvas = document.getElementById('chart2');
    if (!canvas) return;
    
    const ctx = canvas.getContext('2d');
    const width = canvas.width;
    const height = canvas.height;
    
    // 清空画布
    ctx.clearRect(0, 0, width, height);
    
    // 设置边距
    const margin = 50;
    const plotWidth = width - 2 * margin;
    const plotHeight = height - 2 * margin;
    
    // 找出数据范围
    const sqrtLengths = data.map(d => d.sqrtLength);
    const periods = data.map(d => d.period);
    const minSqrtLength = Math.min(...sqrtLengths);
    const maxSqrtLength = Math.max(...sqrtLengths);
    const minPeriod = Math.min(...periods);
    const maxPeriod = Math.max(...periods);
    
    // 处理数据范围为零的情况
    const sqrtLengthRange = maxSqrtLength - minSqrtLength;
    const periodRange = maxPeriod - minPeriod;
    
    // 如果摆长范围为零，设置一个合理的显示范围
    let displayMinSqrtLength, displayMaxSqrtLength, displayMinPeriod, displayMaxPeriod;
    
    if (sqrtLengthRange === 0) {
      // 当√L相同时，以当前√L为中心，设置一个合理的显示范围
      displayMinSqrtLength = minSqrtLength - 2;  // 显示范围：当前√L±2
      displayMaxSqrtLength = minSqrtLength + 2;
    } else {
      displayMinSqrtLength = minSqrtLength;
      displayMaxSqrtLength = maxSqrtLength;
    }
    
    if (periodRange === 0) {
      // 当周期相同时，以当前周期为中心，设置一个合理的显示范围
      displayMinPeriod = minPeriod - 0.5;  // 显示范围：当前周期±0.5s
      displayMaxPeriod = minPeriod + 0.5;
    } else {
      displayMinPeriod = minPeriod;
      displayMaxPeriod = maxPeriod;
    }
    
    const displaySqrtLengthRange = displayMaxSqrtLength - displayMinSqrtLength;
    const displayPeriodRange = displayMaxPeriod - displayMinPeriod;
    
    // 坐标轴
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(margin, margin);
    ctx.lineTo(margin, height - margin);
    ctx.lineTo(width - margin, height - margin);
    ctx.stroke();
    
    // 绘制坐标轴刻度
    ctx.fillStyle = '#333';
    ctx.font = '12px Arial';
    ctx.textAlign = 'center';
    
    // X轴刻度
    const xTicks = 5;
    for (let i = 0; i <= xTicks; i++) {
      const sqrtLength = displayMinSqrtLength + (displayMaxSqrtLength - displayMinSqrtLength) * i / xTicks;
      const x = margin + (sqrtLength - displayMinSqrtLength) / displaySqrtLengthRange * plotWidth;
      const y = height - margin;
      
      // 绘制刻度线
      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x, y + 5);
      ctx.stroke();
      
      // 绘制刻度标签
      ctx.fillText(sqrtLength.toFixed(1), x, y + 20);
    }
    
    // Y轴刻度
    const yTicks = 5;
    for (let i = 0; i <= yTicks; i++) {
      const period = displayMaxPeriod - (displayMaxPeriod - displayMinPeriod) * i / yTicks;
      const x = margin;
      const y = margin + (period - displayMinPeriod) / displayPeriodRange * plotHeight;
      
      // 绘制刻度线
      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x - 5, y);
      ctx.stroke();
      
      // 绘制刻度标签
      ctx.textAlign = 'right';
      ctx.fillText(period.toFixed(2), x - 10, y + 4);
    }
    
    // 绘制散点
    ctx.fillStyle = '#ff6b6b';
    data.forEach(d => {
      const x = margin + (d.sqrtLength - displayMinSqrtLength) / displaySqrtLengthRange * plotWidth;
      const y = height - margin - (d.period - displayMinPeriod) / displayPeriodRange * plotHeight;
      
      ctx.beginPath();
      ctx.arc(x, y, 4, 0, 2 * Math.PI);
      ctx.fill();
    });
    
    // 绘制线性拟合线
    ctx.strokeStyle = '#4caf50';
    ctx.lineWidth = 2;
    ctx.beginPath();
    
    const steps = 100;
    for (let i = 0; i <= steps; i++) {
      const sqrtLength = displayMinSqrtLength + displaySqrtLengthRange * i / steps;
      const period = 2 * Math.PI / Math.sqrt(9.8) * sqrtLength / 10;
      const x = margin + (sqrtLength - displayMinSqrtLength) / displaySqrtLengthRange * plotWidth;
      const y = height - margin - (period - displayMinPeriod) / displayPeriodRange * plotHeight;
      
      if (i === 0) {
        ctx.moveTo(x, y);
      } else {
        ctx.lineTo(x, y);
      }
    }
    ctx.stroke();
    
    // 标签
    ctx.fillStyle = '#333';
    ctx.font = '14px Arial';
    ctx.textAlign = 'center';
    ctx.fillText('√L (cm^0.5)', width / 2, height - 10);
    
    ctx.save();
    ctx.translate(10, height / 2);
    ctx.rotate(-Math.PI / 2);
    ctx.fillText('周期 T (s)', 0, 0);
    ctx.restore();
  },

  /**
   * 绘制 g vs L 图表
   */
  drawGvsLChart(data) {
    const canvas = document.getElementById('chart3');
    if (!canvas) return;
    
    const ctx = canvas.getContext('2d');
    const width = canvas.width;
    const height = canvas.height;
    
    // 清空画布
    ctx.clearRect(0, 0, width, height);
    
    // 设置边距
    const margin = 50;
    const plotWidth = width - 2 * margin;
    const plotHeight = height - 2 * margin;
    
    // 计算重力加速度数据
    const gData = data.map(d => ({
      length: d.length,
      g: 4 * Math.PI * Math.PI * d.length / 100 / (d.period * d.period)
    }));
    
    // 找出数据范围
    const lengths = gData.map(d => d.length);
    const gValues = gData.map(d => d.g);
    const minLength = Math.min(...lengths);
    const maxLength = Math.max(...lengths);
    const minG = Math.min(...gValues);
    const maxG = Math.max(...gValues);
    
    // 处理数据范围为零的情况
    const lengthRange = maxLength - minLength;
    const gRange = maxG - minG;
    
    // 如果摆长范围为零，设置一个合理的显示范围
    let displayMinLength, displayMaxLength, displayMinG, displayMaxG;
    
    if (lengthRange === 0) {
      // 当摆长相同时，以当前摆长为中心，设置一个合理的显示范围
      displayMinLength = minLength - 20;  // 显示范围：当前摆长±20cm
      displayMaxLength = minLength + 20;
    } else {
      displayMinLength = minLength;
      displayMaxLength = maxLength;
    }
    
    if (gRange === 0) {
      // 当重力加速度相同时，以当前重力加速度为中心，设置一个合理的显示范围
      displayMinG = minG - 2;  // 显示范围：当前重力加速度±2 m/s²
      displayMaxG = minG + 2;
    } else {
      displayMinG = minG;
      displayMaxG = maxG;
    }
    
    const displayLengthRange = displayMaxLength - displayMinLength;
    const displayGRange = displayMaxG - displayMinG;
    
    // 坐标轴
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(margin, margin);
    ctx.lineTo(margin, height - margin);
    ctx.lineTo(width - margin, height - margin);
    ctx.stroke();
    
    // 绘制坐标轴刻度
    ctx.fillStyle = '#333';
    ctx.font = '12px Arial';
    ctx.textAlign = 'center';
    
    // X轴刻度
    const xTicks = 5;
    for (let i = 0; i <= xTicks; i++) {
      const length = displayMinLength + (displayMaxLength - displayMinLength) * i / xTicks;
      const x = margin + (length - displayMinLength) / displayLengthRange * plotWidth;
      const y = height - margin;
      
      // 绘制刻度线
      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x, y + 5);
      ctx.stroke();
      
      // 绘制刻度标签
      ctx.fillText(length.toFixed(0), x, y + 20);
    }
    
    // Y轴刻度
    const yTicks = 5;
    for (let i = 0; i <= yTicks; i++) {
      const g = displayMaxG - (displayMaxG - displayMinG) * i / yTicks;
      const x = margin;
      const y = margin + (g - displayMinG) / displayGRange * plotHeight;
      
      // 绘制刻度线
      ctx.beginPath();
      ctx.moveTo(x, y);
      ctx.lineTo(x - 5, y);
      ctx.stroke();
      
      // 绘制刻度标签
      ctx.textAlign = 'right';
      ctx.fillText(g.toFixed(1), x - 10, y + 4);
    }
    
    // 绘制散点
    ctx.fillStyle = '#ff6b6b';
    gData.forEach(d => {
      const x = margin + (d.length - displayMinLength) / displayLengthRange * plotWidth;
      const y = height - margin - (d.g - displayMinG) / displayGRange * plotHeight;
      
      ctx.beginPath();
      ctx.arc(x, y, 4, 0, 2 * Math.PI);
      ctx.fill();
    });
    
    // 绘制标准重力加速度参考线
    const standardG = 9.873;
    const standardY = height - margin - (standardG - displayMinG) / displayGRange * plotHeight;
    
    ctx.strokeStyle = '#4caf50';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(margin, standardY);
    ctx.lineTo(width - margin, standardY);
    ctx.stroke();
    
    // 标签
    ctx.fillStyle = '#333';
    ctx.font = '14px Arial';
    ctx.textAlign = 'center';
    ctx.fillText('摆长 L (cm)', width / 2, height - 10);
    
    ctx.save();
    ctx.translate(10, height / 2);
    ctx.rotate(-Math.PI / 2);
    ctx.fillText('重力加速度 g (m/s²)', 0, 0);
    ctx.restore();
  },

  /**
   * 绘制小摆角下的 T vs θ 图表
   */
  drawTvsSmallThetaChart(data) {
    const canvas = document.getElementById('chart4');
    if (!canvas) return;
    
    const ctx = canvas.getContext('2d');
    const width = canvas.width;
    const height = canvas.height;
    
    // 清空画布
    ctx.clearRect(0, 0, width, height);
    
    // 设置边距
    const margin = 50;
    const plotWidth = width - 2 * margin;
    const plotHeight = height - 2 * margin;
    
    // 筛选小摆角数据（1-10°）
    const smallAngleData = data.filter(d => d.initialAngle >= 1 && d.initialAngle <= 10);
    
    if (smallAngleData.length === 0) {
      ctx.fillStyle = '#f0f0f0';
      ctx.fillRect(0, 0, width, height);
      ctx.fillStyle = '#666';
      ctx.font = '16px Arial';
      ctx.textAlign = 'center';
      ctx.fillText('暂无小摆角数据', width/2, height/2);
      return;
    }
    
    // 找出数据范围
    const angles = smallAngleData.map(d => d.initialAngle);
    const periods = smallAngleData.map(d => d.period);
    const minAngle = Math.min(...angles);
    const maxAngle = Math.max(...angles);
    const minPeriod = Math.min(...periods);
    const maxPeriod = Math.max(...periods);
    
    // 处理数据范围为零的情况
    const angleRange = maxAngle - minAngle;
    const periodRange = maxPeriod - minPeriod;
    
    // 如果角度范围为零，设置一个小的范围来显示点
    const effectiveAngleRange = angleRange === 0 ? 5 : angleRange;
    const effectivePeriodRange = periodRange === 0 ? 1 : periodRange;
    
    // 坐标轴
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(margin, margin);
    ctx.lineTo(margin, height - margin);
    ctx.lineTo(width - margin, height - margin);
    ctx.stroke();
    
    // 绘制散点
    ctx.fillStyle = '#ff6b6b';
    smallAngleData.forEach(d => {
      const x = margin + (d.initialAngle - minAngle) / effectiveAngleRange * plotWidth;
      const y = height - margin - (d.period - minPeriod) / effectivePeriodRange * plotHeight;
      
      ctx.beginPath();
      ctx.arc(x, y, 4, 0, 2 * Math.PI);
      ctx.fill();
    });
    
    // 绘制线性拟合线（只有当角度范围不为零时才绘制）
    if (angleRange > 0) {
      ctx.strokeStyle = '#4caf50';
      ctx.lineWidth = 2;
      ctx.beginPath();
      
      const avgPeriod = periods.reduce((a, b) => a + b) / periods.length;
      ctx.moveTo(margin, height - margin - (avgPeriod - minPeriod) / periodRange * plotHeight);
      ctx.lineTo(width - margin, height - margin - (avgPeriod - minPeriod) / periodRange * plotHeight);
      ctx.stroke();
    }
    
    // 标签
    ctx.fillStyle = '#333';
    ctx.font = '14px Arial';
    ctx.textAlign = 'center';
    ctx.fillText('摆角 θ (°)', width / 2, height - 10);
    
    ctx.save();
    ctx.translate(10, height / 2);
    ctx.rotate(-Math.PI / 2);
    ctx.fillText('周期 T (s)', 0, 0);
    ctx.restore();
  },

  /**
   * 绘制 T vs θ 图表
   */
  drawTvsLargeThetaChart(data) {
    const canvas = document.getElementById('chart5');
    if (!canvas) return;
    
    const ctx = canvas.getContext('2d');
    const width = canvas.width;
    const height = canvas.height;
    
    // 清空画布
    ctx.clearRect(0, 0, width, height);
    
    // 设置边距
    const margin = 50;
    const plotWidth = width - 2 * margin;
    const plotHeight = height - 2 * margin;
    
    // 筛选大摆角数据（30-90°）
    const largeAngleData = data.filter(d => d.initialAngle >= 30 && d.initialAngle <= 90);
    
    if (largeAngleData.length === 0) {
      ctx.fillStyle = '#f0f0f0';
      ctx.fillRect(0, 0, width, height);
      ctx.fillStyle = '#666';
      ctx.font = '16px Arial';
      ctx.textAlign = 'center';
      ctx.fillText('暂无大摆角数据', width/2, height/2);
      return;
    }
    
    // 计算理论周期T0
    const calculateT0 = (length) => 2 * Math.PI * Math.sqrt(length / 100 / 9.8);
    
    // 处理数据，计算T/T0
    const processedData = largeAngleData.map(d => ({
      angle: d.initialAngle,
      tRatio: d.period / calculateT0(d.length)
    }));
    
    // 找出数据范围
    const angles = processedData.map(d => d.angle);
    const tRatios = processedData.map(d => d.tRatio);
    const minAngle = Math.min(...angles);
    const maxAngle = Math.max(...angles);
    const minRatio = Math.min(...tRatios);
    const maxRatio = Math.max(...tRatios);
    
    // 处理数据范围为零的情况
    const angleRange = maxAngle - minAngle;
    const ratioRange = maxRatio - minRatio;
    
    // 如果角度范围为零，设置一个小的范围来显示点
    const effectiveAngleRange = angleRange === 0 ? 10 : angleRange;
    const effectiveRatioRange = ratioRange === 0 ? 0.2 : ratioRange;
    
    // 坐标轴
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(margin, margin);
    ctx.lineTo(margin, height - margin);
    ctx.lineTo(width - margin, height - margin);
    ctx.stroke();
    
    // 绘制散点
    ctx.fillStyle = '#ff6b6b';
    processedData.forEach(d => {
      const x = margin + (d.angle - minAngle) / effectiveAngleRange * plotWidth;
      const y = height - margin - (d.tRatio - minRatio) / effectiveRatioRange * plotHeight;
      
      ctx.beginPath();
      ctx.arc(x, y, 4, 0, 2 * Math.PI);
      ctx.fill();
    });
    
    // 绘制参考线 T/T0 = 1（只有当角度范围不为零时才绘制）
    if (angleRange > 0) {
      ctx.strokeStyle = '#4caf50';
      ctx.lineWidth = 2;
      ctx.beginPath();
      const refY = height - margin - (1 - minRatio) / ratioRange * plotHeight;
      ctx.moveTo(margin, refY);
      ctx.lineTo(width - margin, refY);
      ctx.stroke();
    }
    
    // 标签
    ctx.fillStyle = '#333';
    ctx.font = '14px Arial';
    ctx.textAlign = 'center';
    ctx.fillText('摆角 θ (°)', width / 2, height - 10);
    
    ctx.save();
    ctx.translate(10, height / 2);
    ctx.rotate(-Math.PI / 2);
    ctx.fillText('T/T₀', 0, 0);
    ctx.restore();
  },

  /**
   * 处理实验数据，返回用于导出/报告的数据结构
   * 依赖全局 experimentGroups
   */
  processExperimentData() {
    console.log('processExperimentData被调用');
    console.log('window.experimentGroups:', window.experimentGroups);
    
    if (!window.experimentGroups || !window.experimentGroups.length) {
      console.log('没有实验数据');
      return [];
    }
    
    const processedData = [];
    window.experimentGroups.forEach((exp, index) => {
      console.log(`处理实验${index + 1}:`, exp);
      if (exp.periods && exp.periods.length > 0) {
        const avgPeriod = exp.periods.reduce((sum, p) => sum + p.duration, 0) / exp.periods.length;
        const theoreticalPeriod = 2 * Math.PI * Math.sqrt(exp.length / 100 / 9.8);
        const sqrtLength = Math.sqrt(exp.length);
        const linearFit = 2 * Math.PI / Math.sqrt(9.8) * sqrtLength / 10;
        const processedItem = {
          length: exp.length,
          period: avgPeriod,
          theoreticalPeriod,
          sqrtLength,
          linearFit,
          initialAngle: exp.initialAngle || 0 // 添加初始角度字段
        };
        console.log(`处理后的数据项${index + 1}:`, processedItem);
        processedData.push(processedItem);
      } else {
        console.log(`实验${index + 1}没有周期数据`);
      }
    });
    
    console.log('最终处理的数据:', processedData);
    return processedData;
  }
};

// 添加模块导出调试信息
console.log('ExportModule模块已加载'); 